
const gfx = cc.gfx;

// 传递位置，UV 及颜色数据
let vfmtPosUvColor = new gfx.VertexFormat([
    { name: gfx.ATTR_POSITION, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
    { name: gfx.ATTR_UV0, type: gfx.ATTR_TYPE_FLOAT32, num: 2 },
    { name: gfx.ATTR_COLOR, type: gfx.ATTR_TYPE_UINT8, num: 4, normalize: true },
]);

let CustomAssembler = {

    // 创建渲染数据
    createData (comp) {
        let renderData = comp.requestRenderData();
        renderData.dataLength = 4;
        renderData.vertexCount = 4;
        renderData.indiceCount = 6;
        return renderData;
    },

    // 更新渲染数据
    updateRenderData (comp) {
        let renderData = comp._renderData;
        if (renderData) {
            this.updateVerts(comp);
        }
    },

    // 填充数据 buffer
    fillBuffers (comp, renderer) {
        let renderData = comp._renderData;
        let data = renderData._data;
        // 指定 buffer 的数据格式，并获取 buffer
        let buffer = renderer.getBuffer('mesh', vfmtPosUvColor),
            vertexOffset = buffer.byteOffset >> 2,
            vertexCount = renderData.vertexCount,
            indiceCount = renderData.indiceCount;

        let indiceOffset = buffer.indiceOffset,
            vertexId = buffer.vertexOffset;
        // 通过设定的顶点数量及顶点索引数量获取 buffer 的数据空间
        buffer.request(vertexCount, indiceCount);

        let color = comp.node._color._val;

        let vbuf = buffer._vData,
            ibuf = buffer._iData,
            uintbuf = buffer._uintVData;
        // 填充顶点缓冲
        for (let i = 0, l = vertexCount; i < l; i++) {
            let vert = data[i];
            vbuf[vertexOffset] = vert.x;
            vbuf[vertexOffset+1] = vert.y;
            vbuf[vertexOffset+2] = vert.u;
            vbuf[vertexOffset+3] = vert.v;
            uintbuf[vertexOffset+4] = color;
            vertexOffset += 5;
        }

        // 填充索引缓冲
        for (let i = 0, l = indiceCount / 6; i < l; i++) {
            ibuf[indiceOffset] = vertexId;
            ibuf[indiceOffset + 1] = vertexId + 1;
            ibuf[indiceOffset + 2] = vertexId + 2;
            ibuf[indiceOffset + 3] = vertexId + 1;
            ibuf[indiceOffset + 4] = vertexId + 3;
            ibuf[indiceOffset + 5] = vertexId + 2;
            indiceOffset += 6;
            vertexId += 4;
        }
    },
    // 准备顶点数据
    updateVerts (comp) {
        let renderData = comp._renderData,
            node = comp.node,
            data = renderData._data,
            cw = node.width, ch = node.height,
            appx = node.anchorX * cw, appy = node.anchorY * ch,
            vl, vb, vr, vt;

        let uv = comp.uv;

        let matrix = node._worldMatrix,
            a = matrix.m00, b = matrix.m01, c = matrix.m04, d = matrix.m05,
            tx = matrix.m12, ty = matrix.m13;
        // 依据锚点计算四个顶点的起始值
        vl = -appx;
        vb = -appy;
        vr = cw - appx;
        vt = ch - appy;

        let al = a * vl,
            ar = a * vr,
            bl = b * vl,
            br = b * vr,
            cb = c * vb,
            ct = c * vt,
            db = d * vb,
            dt = d * vt;

        let offset = 0;

        // 左下
        data[offset].x = al + cb + tx;
        data[offset].y = bl + db + ty;
        data[offset].u = uv[0];
        data[offset].v = uv[1];
        offset++;

        // 右下
        data[offset].x = ar + cb + tx;
        data[offset].y = br + db + ty;
        data[offset].u = uv[2];
        data[offset].v = uv[3];
        offset++;

        // 左上
        data[offset].x = al + ct + tx;
        data[offset].y = bl + dt + ty;
        data[offset].u = uv[4];
        data[offset].v = uv[5];
        offset++;

        // 右上
        data[offset].x = ar + ct + tx;
        data[offset].y = br + dt + ty;
        data[offset].u = uv[6];
        data[offset].v = uv[7];
        offset++;
    }
};


cc.Class({
    extends: cc.RenderComponent,
    mixins: [cc.BlendFunc],

    properties: {
        // 渲染组件使用的 Texture
        _texture: {
            default: null,
            type: cc.Texture2D
        },

        texture: {
            get: function () {
                return this._texture;
            },
            set: function (value) {
                this._texture = value;
                this._activateMaterial();
            },
            type: cc.Texture2D,
        },
    },

    // LIFE-CYCLE CALLBACKS:
    ctor(){
        // 顶点数据装配器
        this._assembler = null;
        // 材质
        this._spriteMaterial = null;

        // 纹理 UV 数据
        this.uv = [];
    },

    onLoad () {
        cc.dynamicAtlasManager.enabled = false;
    },

    start () {

    },

    // 组件激活时链接组件的 Assembler，处理UV数据及事件监听。
    onEnable(){
        this._super();
        this._updateAssembler();
        this._activateMaterial();
        this._calculateUV();

        this.node.on(cc.Node.EventType.SIZE_CHANGED, this._onNodeSizeDirty, this);
        this.node.on(cc.Node.EventType.ANCHOR_CHANGED, this._onNodeSizeDirty, this);
    },

    // 组件禁用时，取消事件监听
    onDisable () {
        this._super();

        this.node.off(cc.Node.EventType.SIZE_CHANGED, this._onNodeSizeDirty, this);
        this.node.off(cc.Node.EventType.ANCHOR_CHANGED, this._onNodeSizeDirty, this);
    },

    // 节点数据变化时需要标记更新组件的渲染状态
    _onNodeSizeDirty () {
        if (!this._renderData) return;
        this.markForUpdateRenderData(true);
    },

    // update (dt) {},

    // 设置组件的 Assembler
    _updateAssembler () {
        let assembler = CustomAssembler;

        if (this._assembler !== assembler) {
            this._assembler = assembler;
            this._renderData = null;
        }

        if (!this._renderData) {
            this._renderData = this._assembler.createData(this);
            this._renderData.material = this._material;
            this.markForUpdateRenderData(true);
        }
    },

    // 创建用于渲染图片的材质
    _activateMaterial () {

        if(this._texture){

            // make sure material is belong to self.
            let material = this.sharedMaterials[0];
            if (!material) {
                material = cc.Material.getInstantiatedBuiltinMaterial('2d-sprite', this);
            }
            else {
                material = cc.Material.getInstantiatedMaterial(material, this);
            }

            // material.useColor = true;
            material.setProperty('texture', this._texture);

            this.setMaterial(0, material);
            this.markForUpdateRenderData(true);
            this.markForRender(true);
        }else{
            this.disableRender();
        }


        // let material = this._material;
        // if (!material) {
        //     material = this._material = new SpriteMaterial();
        // }
        // // 是否使用 Uniform 变量传递节点颜色
        // material.useColor = true;
        // if (this._texture) {
        //     material.texture = this._texture;
        //     // 标记渲染组件的渲染状态
        //     this.markForUpdateRenderData(true);
        //     this.markForRender(true);
        //
        //     // _updateMaterial
        //     material.setProperty('texture',this._texture);
        //     this.setMaterial(0, material);
        // } else {
        //     this.disableRender();
        // }

        // _updateMaterial(material)
    },

    // _updateMaterial(material){
    //     material.setProperty('texture', spriteFrame.getTexture());
    //
    //     this.setMaterial(0, material);
    //     this.markForRender(true);
    // },

    // 设置纹理的 UV 数据
    _calculateUV () {
        let uv = this.uv;
        // 设置纹理 UV 起始值
        let l = 0, r = 1, b = 1,t = 0;

        uv[0] = l;
        uv[1] = b;
        uv[2] = r;
        uv[3] = b;
        uv[4] = l;
        uv[5] = t;
        uv[6] = r;
        uv[7] = t;
    }
});
